package com.leyou.trade.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.auth.local.UserContext;
import com.leyou.common.exceptions.LyException;
import com.leyou.item.client.ItemClient;
import com.leyou.item.dto.SkuDTO;
import com.leyou.trade.dto.OrderFormDTO;
import com.leyou.trade.entity.Order;
import com.leyou.trade.entity.OrderDetail;
import com.leyou.trade.entity.OrderLogistics;
import com.leyou.trade.enums.OrderStatus;
import com.leyou.trade.mapper.OrderMapper;
import com.leyou.trade.service.OrderDetailService;
import com.leyou.trade.service.OrderLogisticsService;
import com.leyou.trade.service.OrderService;
import com.leyou.trade.utils.PayHelper;
import com.leyou.user.client.UserClient;
import com.leyou.user.dto.AddressDTO;
import feign.FeignException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author 虎哥
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private ItemClient itemClient;
    @Autowired
    private OrderDetailService detailService;
    @Autowired
    private OrderLogisticsService logisticsService;
    @Autowired
    private UserClient userClient;

    @Override
    @Transactional
    public Long createOrder(OrderFormDTO orderFormDTO) {
        // 1.新增订单
        Order order = new Order();
        // 1.1.金额相关数据
        Map<Long, Integer> carts = orderFormDTO.getCarts();
        // 1)获取商品id，根据id查询出商品
        Set<Long> skuIds = carts.keySet();
        List<SkuDTO> skuDTOList = itemClient.querySkuByIds(skuIds);
        // 2)计算商品总金额
        long total = 0;
        for (SkuDTO skuDTO : skuDTOList) {
            // 获取商品购买的数量
            Integer num = carts.get(skuDTO.getId());
            // 计算
            total += skuDTO.getPrice() * num;
            // 判断下架状态
            if (!skuDTO.getSaleable()) {
                // 商品已经下架
                throw new LyException(500, "商品已经下架，无法下单！");
            }
        }
        order.setTotalFee(total);
        order.setPostFee(0L);
        order.setActualFee(order.getTotalFee() + order.getPostFee()/*减去优惠金额*/);
        order.setPaymentType(orderFormDTO.getPaymentType());
        // 1.2.用户信息
        Long userId = UserContext.getUser().getId();
        order.setUserId(userId);
        // 1.3.状态
        order.setStatus(OrderStatus.INIT.getValue());
        // 1.4.写入数据库
        boolean success = save(order);
        if (!success) {
            // 订单新增失败
            throw new LyException(500, "订单新增失败");
        }
        // 1.5.回显id
        Long orderId = order.getOrderId();

        // 2.新增订单详情
        // 2.1.定义detail集合，用以封装OrderDetail
        List<OrderDetail> details = new ArrayList<>(skuDTOList.size());
        // 2.2.遍历sku，转换detail
        for (SkuDTO skuDTO : skuDTOList) {
            // 获取商品购买的数量
            Integer num = carts.get(skuDTO.getId());
            // 封装detail
            details.add(transferSku2Detail(skuDTO, num, orderId));
        }
        // 2.3.写入数据库
        detailService.saveBatch(details);

        // 3.新增订单物流
        // 3.1.获取addressId
        Long addressId = orderFormDTO.getAddressId();
        // 3.2.去用户服务根据地址id查询地址信息
        AddressDTO addressDTO = null;
        try {
            addressDTO = userClient.queryAddressById(addressId);
        } catch (FeignException e) {
            throw new LyException(e.status(), e.contentUTF8());
        }
        if (!userId.equals(addressDTO.getUserId())) {
            // 证明地址不属于当前用户，数据有误
            throw new LyException(400, "请求参数有误！");
        }
        // 3.3.把信息封装到OrderLogistics
        OrderLogistics orderLogistics = addressDTO.toEntity(OrderLogistics.class);
        orderLogistics.setOrderId(orderId);
        success = logisticsService.save(orderLogistics);
        if (!success) {
            // 订单新增失败
            throw new LyException(500, "订单新增失败");
        }

        try {
            // 4.扣减库存
            itemClient.deductStock(carts);
        } catch (FeignException e) {
            throw new LyException(e.status(), e.contentUTF8());
        }

        // TODO 5.清理购物车
        return orderId;
    }

    @Autowired
    private PayHelper payHelper;

    @Override
    public String getPayUrl(Long orderId) {
        // 查询订单
        Order order = getById(orderId);
        // 健壮性判断
        if (order == null) {
            // 不存在
            throw new LyException(400, "订单id错误，订单不存在！");
        }
        // 订单状态判断
        Integer status = order.getStatus();
        if(!status.equals(OrderStatus.INIT.getValue())){
            // 已付款或已关闭，无法支付
            throw new LyException(400, "订单已付款或已关闭");
        }

        // 获取金额
        Long actualFee = order.getActualFee();
        // 获取url
        return payHelper.getPayUrl(orderId, actualFee);
    }

    private OrderDetail transferSku2Detail(SkuDTO skuDTO, Integer num, Long orderId) {
        OrderDetail detail = new OrderDetail();
        detail.setTitle(skuDTO.getTitle());
        detail.setSpec(skuDTO.getSpecialSpec());
        detail.setSkuId(skuDTO.getId());
        detail.setPrice(skuDTO.getPrice());
        detail.setOrderId(orderId);
        detail.setNum(num);
        detail.setImage(StringUtils.substringBefore(skuDTO.getImages(), ","));
        return detail;
    }
}